package cool.lichuan.framework.config.satoken;

import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cool.lichuan.common.constant.Constants;
import cool.lichuan.common.domain.UserDetail;
import cool.lichuan.common.util.SaUtil;
import cool.lichuan.common.util.ServletUtils;
import cool.lichuan.common.util.ip.AddressUtils;
import cool.lichuan.common.util.ip.IpUtils;
import cool.lichuan.project.system.domain.LoginLog;
import cool.lichuan.project.system.service.LoginLogService;
import cool.lichuan.project.system.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 自定义侦听器的实现
 *
 * @author tenyears
 * @date 2021/7/25 14:00
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class MySaTokenListener implements SaTokenListener {
    private final UserService userService;

    private final LoginLogService loginLogService;

    /**
     * 每次登录时触发
     */
    @Override
    public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {
        log.info("loginType=[ {} ]， loginId=[ {} ]， device=[ {} ]", loginType, loginId, loginModel.getDevice());
        // 查询登陆用户的信息
        UserDetail detail = userService.getUserDetailById(Convert.toLong(loginId));
        // 保存登陆信息
        UserAgent ua = UserAgentUtil.parse(ServletUtils.getUserAgent());
        String tokenValue = StpUtil.getTokenValueByLoginId(loginId, loginModel.getDevice());
        String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
        String loginLocation = AddressUtils.getRealAddressByIP(ipAddr);
        String browser = ua.getBrowser().toString();
        String engine = ua.getEngine().toString();
        String os = ua.getOs().toString();
        String platform = ua.getPlatform().toString();
        String mobile = ua.isMobile() ? Constants.EXIST_OR_STATUS_OK_0 : Constants.DELETED_OR_STATUS_FAIL_1;
        String deptName = detail.getDeptName();
        LoginLog loginLog = new LoginLog(tokenValue, detail.getUserId(), detail.getNickName(), ipAddr, loginLocation,
                browser, engine, os, platform, mobile, loginType, LocalDateTime.now(), deptName);

        loginLogService.save(loginLog);
        // 保存用户信息到session
        detail.setLoginLog(loginLog);
        SaUtil.setUserSession(detail);
    }

    /**
     * 每次注销时触发
     */
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        // ...
        log.error("loginType=[ {} ]， loginId=[ {} ]， tokenValue=[ {} ]", loginType, loginId, tokenValue);
    }

    /** 每次被踢下线时触发 */
    @Override
    public void doKickout(String s, Object o, String s1) {

    }

    /** 每次被顶下线时触发 */
    @Override
    public void doReplaced(String s, Object o, String s1) {

    }

    /**
     * 每次被封禁时触发
     */
    @Override
    public void doDisable(String loginType, Object loginId, long disableTime) {
        // ...
    }

    /**
     * 每次被解封时触发
     */
    @Override
    public void doUntieDisable(String loginType, Object loginId) {
        // ...
    }

    /**
     * 每次创建Session时触发
     */
    @Override
    public void doCreateSession(String id) {
        // ...
    }

    /**
     * 每次注销Session时触发
     */
    @Override
    public void doLogoutSession(String id) {
        // ...
    }
}
